package lt.marsrutai.mobile.android.map.overlay;

import java.util.ArrayList;
import java.util.List;

import android.app.ActionBar.LayoutParams;
import android.graphics.drawable.Drawable;
import android.view.View;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

/**
 * Holds items that can be "tapped". When an item is tapped, a balloon is
 * displayed with information. {@link BalloonView} decides which information and
 * how is displayed in the balloon.
 * 
 * @author Justas
 */
public class TappableOverlayContainer<T extends OverlayItem> extends ItemizedOverlay<T> {
    
    private List<T> overlays = new ArrayList<T>();
    private MapView mapView;
    private BalloonView<T> balloonView;

    public TappableOverlayContainer(MapView mapView, Drawable defaultMarker, BalloonView<T> balloonView) {
        super(boundCenterBottom(defaultMarker));
        
        this.balloonView = balloonView;
        this.mapView = mapView;
        mapView.addView(balloonView);
    }

    /**
     * Each time overlay is added, populate must be called to prepare overlays
     * to be drawn.
     *
     * @param stop
     */
    public void addOverlay(T overlayItem) {
        overlays.add(overlayItem);
        populate();
    }
    
    /**
     * Delegate for {@link ItemizedOverlay#boundCenterBottom(Drawable)}
     * 
     * @param marker
     * @return
     */
    public static Drawable boundCenterBottom(Drawable marker) {
        return ItemizedOverlay.boundCenterBottom(marker);
    }

    /**
     * Called by ItemizedOverlay.populate().
     */
    @Override
    protected T createItem(int i) {
        return overlays.get(i);
    }
    
    @Override
    public int size() {
        return overlays.size();
    }
    
    @Override
    public boolean onTap(int index) {
        T tappedItem = overlays.get(index);
        
        displayPopup(tappedItem);
        
        mapView.getController().animateTo(tappedItem.getPoint());

        return true;
    }
    
    /**
     * Called regardless of whether an item was tapped or not.
     */
    @Override
    public boolean onTap(GeoPoint p, MapView mapView) {
        // Returns false if tap happend on an empty area (i.e. area without items).
        boolean itemTapped = super.onTap(p, mapView);
        
        if (!itemTapped && balloonView != null && balloonView.getVisibility() == View.VISIBLE) {
            // Make the popup disappear when the blank area is tapped.
            balloonView.setVisibility(View.GONE);            
        }
        
        return itemTapped;
    }
    
    /**
     * Displays the popup at the item with the item's details.
     * 
     * @param item
     */
    private void displayPopup(T item) {
        balloonView.setData(item);

        GeoPoint point = item.getPoint();
        MapView.LayoutParams layoutParams = new MapView.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, point,
                MapView.LayoutParams.BOTTOM_CENTER);
        layoutParams.mode = MapView.LayoutParams.MODE_MAP;

        balloonView.setVisibility(View.VISIBLE);
        balloonView.setLayoutParams(layoutParams);
    }
}
